package com.ives.launcher.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;

import com.ives.launcher.R;
import com.ives.launcher.logic.DragContainer;
import com.ives.launcher.model.ItemInfo_App;
import com.ives.launcher.util.ILog;
/**
 * 桌面中的每一页（每一屏）， 将屏幕分成4x5的格子，每一个item占据一格或多格 用于接收被拖动的item，或者提供被拖动的item
 * 维护自己的item的位置，状态等信息
 * 此类并不拦截任何触摸事件，因为并不需要在此层处理此类事件
 * 本来的作用是帮助其他类找到操作的对象
 * @author ives
 * 
 */
public class View_Page_Item extends ViewGroup implements DragContainer {
	private int index;//所在父类中的位置(若在xml中添加，就在xml中指定)
	private boolean isHorizontal;// 是否是横屏

	private int cellWidthp;// 单项宽度(像素)
	private int cellHeight;// 单项高度

	private int xCells;// x轴Cell数量(列数)
	private int yCells;// y轴cell数量（行数）

	private int iconXGap=15;// 宽度间距（单元格内与icon与单元格之间的间距）
	private int iconYGap=15;// 高度间距（单元格内与icon与单元格之间的间距）
	//标志哪些位置被占据，哪些为空
	private boolean [][] postions;
	/*自定义*/
    private View_Root view_manager;//是否只是拿来显示app的。
	
	public View_Page_Item(Context context) {
		this(context, null);
	}
	
	public View_Page_Item(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public View_Page_Item(Context context,int width,int height){
		super(context);
		xCells = width;
		yCells = height;
		postions = new boolean[xCells][yCells];
		addListener();
		setBackgroundColor(Color.TRANSPARENT);
	}
	public View_Page_Item(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		addListener();
		/* 解析自定义的属性 */
		TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.CellLayout, defStyle, 0);
		cellWidthp = a.getDimensionPixelSize(R.styleable.CellLayout_cellWidth,130);
		cellHeight = a.getDimensionPixelSize(R.styleable.CellLayout_cellHeight,130);
		xCells = a.getInt(R.styleable.CellLayout_xCells, 4);
		yCells = a.getInt(R.styleable.CellLayout_yCells, 4);

		a.recycle();// 用完就回收资源
		//初始化
		postions = new boolean[xCells][yCells];
		setBackgroundColor(Color.TRANSPARENT);
		
	}
	
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        
        if (widthMode != MeasureSpec.EXACTLY || heightMode != MeasureSpec.EXACTLY){
           // throw new IllegalStateException("ApplicationsStackLayout can only be used with " + "measure spec mode=EXACTLY");
        }
        setMeasuredDimension(widthSize, heightSize);
        calculateCellSize(widthSize, heightSize);//计算并设置每个单元的大小
	}

	public void setSize(int w,int h){
		this.getLayoutParams().width = w;
		this.getLayoutParams().height = h;
		setMeasuredDimension(w, h);
		calculateCellSize(w, h);//计算并设置每个单元的大小
		onLayout(true, (index-1)*w,0, index*w, h);
	}
	/**
	 * 此类中最重要的方法，用来对子对象进行布局
	 */
	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		int count = getChildCount();
		for (int i = 0; i < count; i++) {
			View_Cell child = (View_Cell) getChildAt(i);
			if (child.getVisibility() != View.GONE) {
				cellLayout(child);
			}
		}
		for (int i = 0; i < yCells; i++) {//列
			for (int j = 0; j < xCells; j++) {//行
				//System.out.println(index+"-----------行"+i+"  列"+j+" "+postions[j][i]);
			}
		}
	}
	/**
	 * 设置某个cell的位置
	 * @param lp
	 */
	protected void cellLayout(View_Cell cell){
		View_Page_Item.LayoutParams lp = (LayoutParams) cell.getLayoutParams();
		//首先确定单项占据的矩形
		int left = lp.startCellsX*cellWidthp;
		int top = lp.startCellsY*cellHeight;
		int right = left+lp.cellWidth*cellWidthp;
		int bottom = top+lp.cellHeight*cellHeight;
		Rect rect = new Rect(left, top, right, bottom);
		//再根据矩形的位置确定单项图标的位置
		cell.layout(left+iconXGap, top+iconYGap, right-iconXGap, bottom-iconYGap);
		/*设置cell的各种常用属性，以便以后使用*/
		lp.width = lp.cellWidth*cellWidthp;
		lp.height =lp.cellHeight*cellHeight;
		
		cell.setMeasureSize(lp.width, lp.height);
		
		//更新postions
		for (int i = 0; i < lp.cellWidth; i++) {
			for (int j = 0; j < lp.cellHeight; j++) {
				postions[lp.startCellsX+i][lp.startCellsY+j] = true;
			}
		}
	}
	/**
	 * 计算单项高度和宽度
	 */
	private void calculateCellSize(int widthSize, int heightSize){
		cellHeight = heightSize/yCells;
		cellWidthp = widthSize/xCells;
	}
	int touchx;
	int touchy;
	/*是否拦截信息，如果拦截，那么事件将不会向下传递*/
	/**
	 * 查找是否有cell被点击
	 */
	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		int action = ev.getAction();//取得动作
		if(action==MotionEvent.ACTION_DOWN){
			touchx= (int) ev.getRawX();
			touchy= (int) ev.getRawY();
		}else if(action==MotionEvent.ACTION_UP){
			view_manager.view_Dragging = null;
		}
		return false;
	}
	/**
	 * 此方法控制处理触摸事件，返回true会让这个事件的发起者（通常是RootView）重新调用onInterceptTouchEvent事件
	 * 返回false就结束了事件再此View中的生命
	 */
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		super.onTouchEvent(event);
		 return true;
	}
	
	
	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		if(View_Root.TOUCH_TYPE==View_Root.TOUCH_TYPE_DRAG_CELL){
			drawDragGrid(canvas);
		}
		
	}
	/**
	 * 拖动过程中需要把网格的角画出来
	 * @param canvas
	 */
	private void drawDragGrid(Canvas canvas){
		if(cellHeight==0 )return;
		Paint paint = new Paint();
		paint.setColor(Color.GREEN);
		paint.setStrokeWidth(1f);
		for (int i = 0; i <= xCells; i++) {
			for (int j = 1; j <=yCells; j++) {
				canvas.drawLine(i*cellWidthp-10, j*cellHeight, i*cellWidthp+10, j*cellHeight, paint);
				canvas.drawLine(i*cellWidthp, j*cellHeight-10, i*cellWidthp, j*cellHeight+10, paint);
			}
		}
		//圈
		paint.setStyle(Style.STROKE);
		canvas.drawRect(0,0,getMeasuredWidth()-1,getMeasuredHeight(), paint);
		
//		//画一个测试的圆点
//		paint.setColor(Color.RED);
//		canvas.drawRect(centerx-15,centery-15,centerx+15,centery+15, paint);
		paint.reset();
	}
	int centerx = 0;
	int centery = 0;
	public void setcurrent(int x,int y,View_Cell view){
		View_Page_Item.LayoutParams lp = (LayoutParams) view.getLayoutParams();
		this.centerx = x+lp.cellWidth*cellWidthp/2;
		this.centery = y+lp.cellHeight*cellHeight/2;
	}
	
	private void addListener(){
		this.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				//查看是否有被点击的cell
				if(View_Cell.clickingView!=null){
					View_Cell.clickingView.setClicking(false);
					View_Cell.clickingView.postInvalidate();
					if(View_Cell.clickingView.getmOnClickLinstener()!=null){
						View_Cell.clickingView.getmOnClickLinstener().onClick();
					}
				}
				View_Cell.clickingView = null;
			}
		});
		this.setOnLongClickListener(new OnLongClickListener() {
			@Override
			public boolean onLongClick(View v) {
				View_Root.isLongPress = true;
				//定位长按的cell
				int childcount = getChildCount();
				Rect rect = new Rect();
				for (int i = 0; i < childcount; i++) {
					if(!(getChildAt(i) instanceof View_Cell))return false;//要求View_Page_Item的子类必须为View_Cell
					View_Cell cell = (View_Cell) getChildAt(i);
					// cell.getHitRect(rect);//取得view所在的矩形(此时是相对位置，需要换算成绝对位置)
					 cell.getGlobalVisibleRect(rect);
					 if(rect.contains(touchx, touchy)){
						 //得到父控件距离x和y的间距
						 int parentxy[] = new int[]{0,0};
						 getLocationOnScreen(parentxy);
						 cell.getStartPoint()[0] = touchx-cell.getLeft()-parentxy[0];
						 cell.getStartPoint()[1] = touchy-cell.getTop()-parentxy[1];
						 //准备创建一次拖动
						 view_manager.view_Dragging = view_manager.makeDragViewFromCell(cell,View_Page_Item.this);
						 view_manager.view_Dragging.setDraggingContainer(View_Page_Item.this);
						 break;
					 }
				}
				return false;
			}
		});
	}
	/**
	 * 检测cell是否可以移动到位置1，如果可以，将cell移动到位置1，如果不可以，强制移动到位置2
	 * 如果移动到位置1成功，则把位置2的位置状态设置成未使用
	 * @param x1 目标位置x
	 * @param y1 目标位置y
	 * @param x2 备用位置x
	 * @param y2 备用位置y
	 * @param cell 要移动的cell
	 */
	@Override
	public boolean moveToPosition(int x,int y,View_Drag drag){
		//首先判断cell在此容器中是否已经存在，如果不存在，还需要先删除，再添加
		View_Page_Item.LayoutParams lp = (LayoutParams) drag.getStartCell().getLayoutParams();
		//首先确定单项占据的矩形
		int left = x*cellWidthp;
		int top = y*cellHeight;
		int right = left+lp.cellWidth*cellWidthp;
		int bottom = top+lp.cellHeight*cellHeight;
		Rect rect = new Rect(left, top, right, bottom);
		if(drag.startGroup!=this){//判断是否跨页面
			if(drag.getStartCell()!=null){
				drag.startGroup.removeCell(drag.getStartCell());
				this.addView(drag.getStartCell());
			}
		}
		//再根据矩形的位置确定单项图标的位置
		drag.getStartCell().layout(left+iconXGap, top+iconYGap, right-iconXGap, bottom-iconYGap);
		
		/*设置cell的各种常用属性，以便以后使用*/
		lp.width = lp.cellWidth*cellWidthp-iconXGap*2;
		lp.height =lp.cellHeight*cellHeight-iconYGap*2;
		lp.startCellsX = x;
		lp.startCellsY = y;
		drag.getStartCell().setMeasureSize(lp.width, lp.height);
		setPositionStatus(x,y,lp.cellWidth,lp.cellHeight,true);//更新postions
//				//更新cell的位置信息
//				cell.setLayoutParams(lp);
		return true;
	}
	@Override
	public View getChildByPosition(int x,int y){
		for (int i = 0; i < getChildCount(); i++) {
			View_Cell cell = (View_Cell) getChildAt(i);
			View_Page_Item.LayoutParams params = (LayoutParams) cell.getLayoutParams();
			Rect rect = new Rect(params.startCellsX,params.startCellsY,params.startCellsX+params.cellWidth,params.startCellsY+params.cellHeight);
			if(rect.contains(x, y))return cell; 
		}
		return null;
	}
	/**
	 * 用于将块区域的状态设置成已使用或未使用
	 * @param x 开始x
	 * @param y 开始y
	 * @param w 宽
	 * @param h 高
	 * @param used 状态(true为已使用，false为未使用)
	 */
	@Override
	public void setPositionStatus(int x,int y,int w,int h,boolean used){
		for (int i = 0; i < w; i++) {
			for (int j = 0; j < h; j++) {
				if(xCells>x+i && yCells>y+j){
					postions[x+i][y+j] = used;
					ILog.w("", "位置状态修改:"+(x+i)+"__"+(y+j)+"   :"+postions[x+i][y+j]);
				}
			}
		}
	}
	/**
	 * 检查某个位置是否可以存放某个cell
	 * @param x
	 * @param y
	 * @param cell
	 * @return true表示可以存放，false表示不可以存放
	 */
	@Override
	public boolean checkCanMoveToPosition(int x,int y,View_Drag drag){
		View_Cell cell = drag.getStartCell();
		View_Page_Item.LayoutParams params = (LayoutParams) cell.getLayoutParams();
		for (int i = 0; i < params.cellWidth; i++) {
			for (int j = 0; j < params.cellHeight; j++) {
				if(xCells>x+i && yCells>y+j){
					if(postions[x+i][y+j]==true){//只要有一个位置被占据，就证明该位置不可用
						return false;
					}
				}
			}
		}
		return true;
	}
	/**
	 * 当停止拖动某个cell的时候，寻找cell在界面上最合适的存放位置
	 * 备注：以cell的中心点在哪个位置，那个位置就是cell最合适的存放位置
	 * @param touchX 触摸点x
	 * @param touchY 触摸点y
	 * @param cell 被拖动的cell
	 * @return 最合适的位置，[0]为x坐标[1]为y坐标，均以xCells和yCells为单位
	 */
	@Override
	public int[] findDropCellFinalPosition(int touchX, int touchY,View_Drag drag) {
		View_Page_Item.LayoutParams params = (LayoutParams) drag.getStartCell().getLayoutParams();
		int xy[] = new int[]{0,0};//容器相对于xy轴的距离
		getLocationOnScreen(xy);
		//cell当前的起始地点
		int left = touchX-drag.getStartCell().getStartPoint()[0]-xy[0];
		int top = touchY-drag.getStartCell().getStartPoint()[1]-xy[1];
		//cell中心点x，y(用于计算应该放在哪里)(这里的点是相对距离)
		int centerX = left+params.cellWidth*cellWidthp/2;
		int centerY = top+params.cellHeight*cellHeight/2;
		//根据中心点找到cell最终应该存放的起始位置(以xCells和yCells为坐标系)
		int finalXCells = centerX/cellWidthp-params.cellWidth/2;
		int finalYCells = centerY/cellHeight-params.cellWidth/2;
		//确保起始x和y不小于0
		finalXCells = finalXCells>0?finalXCells:0;
		finalYCells = finalYCells>0?finalYCells:0;
		//判断cell的最终位置是否可用，如果不可用，则寻找就近的位置，如果找不到，则返回拖动cell前的位置
		return new int[]{finalXCells,finalYCells};
//		boolean isUsedFinalPosition = false;//要判断的位置是否被占据
//		label:
//		for (int i = 0; i < params.cellWidth; i++) {
//			for (int j = 0; j < params.cellHeight; j++) {
//				//范围判断
//				if(xCells>(finalXCells+i) && yCells>(finalYCells+j)){
//					if(postions[finalXCells+i][finalYCells+j]==true){//只要有一个位置被占据，就证明该位置不可用
//						//return view_manager.lastPoint;//返回拖动cell前的位置
//						isUsedFinalPosition = true;
//						break label;
//					}
//				}else{
//					System.out.println("超出了x:"+(i+finalXCells));
//					System.out.println("超出了y:"+(j+finalYCells));
//				}
//				
//			}
//		}
//		if(isUsedFinalPosition){//如果最合适的位置已经被占据，就寻找就近的位置
//			return autoFindNearbyPositions(finalXCells,finalYCells,drag.getStartCell());
//		}else{
//			//如果当前cell的起始位置+cell的宽度或高度超出了容器大小（也就是大于xCells或者yCells），那么仍然需要就近寻找合适的位置
//			if((finalXCells+params.cellWidth-1)<xCells && (finalYCells+params.cellHeight-1)<yCells){
//				return new int[]{finalXCells,finalYCells};//范围之内，返回
//			}else{//范围之外，寻找就近位置
//				return autoFindNearbyPositions(finalXCells,finalYCells,drag.getStartCell());	
//			}
//		}
	}
	/**
	 * 在停止拖动某个cell的是时候，为cell寻找就近的存放位置
	 * @param x 最合适的位置x坐标（以xCells为参照）
	 * @param y 最合适的位置y坐标（以yCells为参照）
	 * @param cell
	 * @return
	 */
	private int[] autoFindNearbyPositions(int x,int y,View_Cell cell){
		/**
		 * 暂时还未实现，所以直接返回cell拖动之前的位置
		 * 打算用广度优先算法来解决此问题
		 */
		return view_manager.lastPoint;
	}
	/**
	 * 测试用，用于输出当前页所有单元格的状态
	 */
	public void printfPositions(){
		for (int i = 0; i < 5; i++) {//列
			for (int j = 0; j < 4; j++) {//行
				//System.out.println(index+"-----------行"+i+"  列"+j+" "+postions[j][i]);
			}
		}
	}
	/******override*******/
	@Override
	public void onDropCompleted(View target, boolean success) {
		ILog.w("onDropCompleted", "index:"+index);
		
	}

	@Override
	public void onDragIn(View view, DragContainer source) {
		view_manager.view_Dragging.setDraggingContainer(this);
		invalidate();
	}

	@Override
	public boolean disposeDrop(MotionEvent event,View_Drag drag) {
		return false;
	}

	@Override
	public void onDropOut(View view, DragContainer target) {

	}
	@Override
	public void removeCell(View_Cell cell) {
		this.removeView(cell);
	}
	/**
	 * 专门用于单个cell的布局
	 * @author ives
	 * 
	 */
	public static class LayoutParams extends ViewGroup.MarginLayoutParams {
		public int startCellsX;//起始列，在父类x坐标中的起始位置（总数为父类的xCells）
		public int startCellsY;//起始行，在父类y坐标中的起始位置（总数为父类的yCells）
		public int cellWidth;//在父类x坐标中占据的单元格数
		public int cellHeight;//在父类y坐标中占据的单元格数;
		//public int xGap;//单元格内内容与单元格x轴的间距(像素)
		//public int yGap;//单元格内内容与单元格y轴的间距(像素)

		
		public LayoutParams(Context c, AttributeSet attrs) {
			super(c, attrs);
		}
		
		public LayoutParams(ViewGroup.LayoutParams source) {
			super(source);
			View_Page_Item.LayoutParams params = (LayoutParams) source;
			this.startCellsX = params.startCellsX;
			this.startCellsY = params.startCellsY;
			this.cellWidth = params.cellWidth;
			this.cellHeight = params.cellHeight;
			
		}
		/**
		 * 
		 * @param startCellsX
		 * @param startCellsY
		 * @param cellWidth
		 * @param cellHeight
		 * @param xgap
		 * @param ygap
		 */
		public LayoutParams(int startCellsX, int startCellsY, int cellWidth, int cellHeight,int xgap,int ygap) {
			super(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
			this.startCellsX = startCellsX;
			this.startCellsY = startCellsY;
			this.cellWidth = cellWidth;
			this.cellHeight = cellHeight;
			//xGap = xgap;
			//yGap = ygap;
		}
	}
	
	/*getter and setter*/
	public View_Root getView_manager() {
		return view_manager;
	}

	public void setView_manager(View_Root view_manager) {
		this.view_manager = view_manager;
	}

	public int getIndex() {
		return index;
	}

	public void setIndex(int index) {
		this.index = index;
	}

	public int getIconXGap() {
		return iconXGap;
	}

	public void setIconXGap(int iconXGap) {
		this.iconXGap = iconXGap;
	}

	public int getIconYGap() {
		return iconYGap;
	}

	public void setIconYGap(int iconYGap) {
		this.iconYGap = iconYGap;
	}

	

	
}
